
package client;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

import node.NodeManager;

import remote.RemoteDistributedHashMap;
import remote.RemoteFuture;

/**
 * @author Team 4 
 */
public class LoadHashMap
{
  /**
   * Registry name
   */
  private static String REGISTRY_NAME = "RemoteRegistry";
  /**
   * rmi registry
   */
  private static Registry registry;
  /**
   * The wait time of client before checking result in seconds.
   */
  private static int WAIT_TIME = 5000;
  /**
   * method to find the rmi name given a node name
   */
  public static String rmi_NodeFind(final int node_num) 
  {
    final String rmi_name_actual = new Integer(node_num).toString() + "A";
    final String rmi_name_virtual = new Integer(node_num).toString() + "V";
    try
    {
      if (registry.lookup(rmi_name_actual) == null)
      {
        return rmi_name_virtual;
      }
      else
      {
        return rmi_name_actual;
      }
    }
    catch (final RemoteException | NotBoundException e)
    {
      System.out.println(" an error occured " + e);
      System.exit(1);
    }
    return rmi_name_virtual;
  }

  /**
   * @param the_args - Command line arguments
   */
  public static void main(final String[] the_args)
  {
    // TODO Auto-generated method stub
    try
    {
      String registry_name = REGISTRY_NAME;
      if (the_args.length < 4)
      {
        System.out
        .println("Usage <rmi registry host> <rmi registry port> <remote rmiregistry name> <wordlistlocation>");
        System.exit(1);
      }
      final String host = the_args[0];
      final int port = Integer.parseInt(the_args[1]);
      registry_name = the_args[2];
      final Registry bootstrap = LocateRegistry.getRegistry(host, port);
      registry = (Registry) bootstrap.lookup(the_args[2]);
      final ArrayList<String> registry_list =  new 
          ArrayList<String>(Arrays.asList(registry.list()));
      System.out.println(" list of nodes in the registry are  " +
          Arrays.toString(registry.list()));
      System.out.println(" Select a node - ");
      final Scanner scanner = new Scanner(System.in);
      String node_name = scanner.nextLine();
      RemoteDistributedHashMap map;
      node_name = node_name.trim();
      if (node_name.isEmpty())
      {
        System.out.println("Hmm, I didn't get node name");
        System.exit(1);
      }
      if (!(node_name.endsWith("V") || node_name.endsWith("A")))
      {
        node_name = rmi_NodeFind(new Integer(node_name).intValue());
      }
      if (!registry_list.contains(node_name))
      {
        System.out.println("the given node number is not found in the rmi registry");
        System.exit(1);
      }
      map = (RemoteDistributedHashMap) registry.lookup(node_name);
      FileInputStream fis;
      fis = new FileInputStream(the_args[3]);
      final InputStreamReader in = new InputStreamReader(fis, "UTF-8");
      final BufferedReader br = new BufferedReader(in);
      String line;
      RemoteFuture result;      
      System.out.println("Populating HashMap from file");
      while ((line = br.readLine()) != null)
      {
        final String[] values = line.split(",");
        final String k = values[0];
        final String v = values[1];
        result = (RemoteFuture) map.put(k, v);
        System.out.println(k + " was mapped to " + result.blockingGet() + " before putting.");
        System.out.println("key " + k + " value " + v + " was stored in the hash map successfully.");
      }
    }
    catch (final FileNotFoundException e)
    {
      System.out.println("Unable to load word.txt");
      System.exit(1);
    }
    catch (final UnsupportedEncodingException e)
    {
      System.out.println("An error occured reading word.txt");
      System.exit(1);
    }
    catch (final IOException e)
    {
      System.out.println("Unable to load word.txt");
      System.exit(1);
    }
    catch (final NotBoundException e)
    {
      System.out.println("Unable to locate the registry");
      System.exit(1);
    }
    catch (final AlreadyBoundException e)
    {
      System.out.println("problem with registry");
      System.exit(1);
    }
  }
}

